package com.hunttown.mes.manage.controller._lbs;

import com.hunttown.mes.common.OperateCode;
import com.hunttown.mes.common.http.HttpClient;
import com.hunttown.mes.common.keys.KeyConstants;
import com.hunttown.mes.manage.controller.common.AdminBaseClass;
import com.hunttown.mes.manage.controller.common.ModelService;
import com.hunttown.mes.rpc.domain.AnalysisManageDTO;
import com.hunttown.mes.rpc.domain.LbsServiceDTO;
import com.hunttown.mes.rpc.domain.LbsTerminalDTO;
import com.hunttown.mes.rpc.domain.LbsTerminalStateDTO;
import com.hunttown.mes.rpc.domain.enums.lbs.TerminalTypeEnum;
import com.hunttown.mes.rpc.domain.query.LbsServiceDTOQuery;
import com.hunttown.mes.rpc.domain.query.LbsTerminalDTOQuery;
import com.hunttown.common.domain.Page;
import com.hunttown.mes.common.utils.JSONUtils;
import com.hunttown.mes.common.utils.StringUtils;
import com.hunttown.mes.manage.service.AnalysisManageManageService;
import com.hunttown.mes.manage.service.LbsServiceManageService;
import com.hunttown.mes.manage.service.LbsTerminalManageService;
import com.hunttown.mes.manage.service.LbsTerminalStateManageService;
import org.json.JSONObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.servlet.http.HttpServletRequest;
import java.util.*;

import static com.hunttown.mes.common.utils.PageUtils.PagePackage;

/**
 * created by wangjunfu on 2021-07-05 11:06:20
 */
@Controller
@RequestMapping(value = "/lbs/terminal")
public class LbsTerminalController {

    private final static Logger logger = LoggerFactory.getLogger(LbsTerminalController.class);

    private final LbsServiceManageService lbsServiceService;
    private final LbsTerminalManageService lbsTerminalService;
    private final LbsTerminalStateManageService lbsTerminalStateService;
    private final AnalysisManageManageService manageService;
    private final ModelService modelService;

    @Autowired
    public LbsTerminalController(LbsServiceManageService lbsServiceService, LbsTerminalManageService lbsTerminalService, LbsTerminalStateManageService lbsTerminalStateService, AnalysisManageManageService manageService, ModelService modelService) {
        this.lbsServiceService = lbsServiceService;
        this.lbsTerminalService = lbsTerminalService;
        this.lbsTerminalStateService = lbsTerminalStateService;
        this.manageService = manageService;
        this.modelService = modelService;
    }

    //region 配置中的高德信息
    @Value("${amap.key}")
    private String amapKey;

    @Value("${amap.version}")
    private String amapVersion;
    //endregion

    //region 数据列表

    /**
     * 首页
     *
     * @param model    model模型
     * @param dtoQuery 查询条件
     * @return model
     */
    @RequestMapping(value = "/index", method = RequestMethod.GET)
    public String index(Model model, LbsTerminalDTOQuery dtoQuery) {

        dtoQuery.setOrderBy("order by id desc");
        Page<LbsTerminalDTO> dataPage = lbsTerminalService.getForPage(dtoQuery);

        for (LbsTerminalDTO item : dataPage.getItems()) {
            item.setServiceName(lbsServiceService.getServiceName(item.getServiceId()));
            item.setTerminalTypeName(TerminalTypeEnum.getEnumByKey(item.getTerminalType()));
            item.setUserName(modelService.getUserTrueName(item.getUserId()));
        }

        model.addAttribute("page", dataPage);
        model.addAttribute("PagePackage", PagePackage(dataPage.getPn(), dataPage.getStart(), dataPage.getPageSize(), dataPage.getTotalPages(), dataPage.getTotalItems()));
        model.addAttribute("dtoQuery", dtoQuery);

        return "lbs/terminal/index";
    }
    //endregion

    //region 编辑&保存

    /**
     * 编辑
     *
     * @param model model模型
     * @param id    主键id
     * @return model
     */
    @RequestMapping(value = "/edit", method = RequestMethod.GET)
    public String edit(Model model, Integer id) {
        id = (id == null ? 0 : id);

        LbsTerminalDTO obj;

        if (id > 0) {
            obj = lbsTerminalService.getById(id);
            obj.setUserName(modelService.getUserTrueName(obj.getUserId()));
        } else {
            obj = new LbsTerminalDTO();
            obj.setId(0);
            obj.setUserId(0);
            obj.setCarId(0);
        }
        model.addAttribute("Obj", obj);

        //终端类型
        model.addAttribute("TerminalTypeList", TerminalTypeEnum.getEnumList());

        //服务信息
        LbsServiceDTOQuery serviceQuery = new LbsServiceDTOQuery();
        serviceQuery.setStopFlag(0);
        Page<LbsServiceDTO> servicePage = lbsServiceService.getForPage(serviceQuery);
        model.addAttribute("servicePage", servicePage);

        return "lbs/terminal/edit";
    }

    /**
     * 保存 ajax异步
     *
     * @param request sevelet请求
     * @param objDTO  实体类
     * @return json
     */
    @RequestMapping(value = "/saveEdit", method = RequestMethod.POST)
    @ResponseBody
    public String saveEditNotify(HttpServletRequest request, LbsTerminalDTO objDTO) {

        // 结果返回 结果至少包含一个操作状态和一条状态信息
        String result = "";
        Map<String, String> map = new HashMap<String, String>();

        try {
            //region 如果是手机则必须绑定用户
            if (objDTO.getTerminalType() == 1 && objDTO.getUserId() <= 0) {
                map = OperateCode.CompositionResult(map, -10, "请绑定用户！");
                result = JSONUtils.toJSON(map);
                return result;
            }
            //endregion

            //region 如果是GPS则必须绑定车辆
            if (objDTO.getTerminalType() == 2 && objDTO.getCarId() <= 0) {
                map = OperateCode.CompositionResult(map, -10, "请绑定车辆！");
                result = JSONUtils.toJSON(map);
                return result;
            }
            //endregion

            //region 【高德】调用高德接口生成唯一Key
            LbsServiceDTO service = lbsServiceService.getFromCacheId(objDTO.getServiceId());

            if (service != null && service.getLbsType() == 1 && StringUtils.isBlank(objDTO.getTerminalKey())) {
                //servicekey 不能为空
                if (StringUtils.isBlank(service.getServiceKey())) {
                    map = OperateCode.CompositionResult(map, -10, "服务项目异常！");
                    result = JSONUtils.toJSON(map);
                    return result;
                }

                String url = "https://tsapi.amap.com/v1/track/terminal/add";
                StringBuilder sb = new StringBuilder();
                sb.append("key=" + KeyConstants.LBS_GAODE_TRACKKEY);
                sb.append("&sid=").append(service.getServiceKey());
                sb.append("&name=").append(objDTO.getTerminalCode());
                String res = HttpClient.doPost(url, sb.toString(), 1);

                //解析结果：{"data":{"name":"imi45682243682","tid":375083043,"sid":364837},"errcode":10000,"errdetail":null,"errmsg":"OK"}
                JSONObject jsonObject = new JSONObject(res);
                if (!jsonObject.get("errcode").equals(10000)) {
                    map = OperateCode.CompositionResult(map, -10, "高德接口调用失败：" + jsonObject.get("errdetail"));
                    result = JSONUtils.toJSON(map);
                    return result;
                }

                JSONObject dataObject = jsonObject.getJSONObject("data");
                objDTO.setTerminalKey(dataObject.get("tid") + "");
            }
            //endregion

            if (objDTO.getId() == null || objDTO.getId() <= 0) {
                //新增
                //设置初始值
                String pin = AdminBaseClass.getPin(request);
                AnalysisManageDTO curr_obj = manageService.getFromCachePin(pin);
                objDTO.setAdminId(curr_obj.getId());
                objDTO.setCreateTime(new Date());
                objDTO.setStopFlag(0);
                objDTO.setDeleteFlag(0);
                objDTO = lbsTerminalService.insert(objDTO);

                if (objDTO == null || objDTO.getId() <= 0) {
                    //操作失败
                    map = OperateCode.CompositionResult(map, -1);
                    result = JSONUtils.toJSON(map);
                    return result;
                }

            } else {
                //更新
                //将不需要更新的字段设置为NULL
                Boolean isNext = lbsTerminalService.updateInfoById(objDTO);

                if (!isNext) {
                    //操作失败
                    map = OperateCode.CompositionResult(map, -1);
                    result = JSONUtils.toJSON(map);
                    return result;
                }
            }

            //操作成功 结果返回
            map = OperateCode.CompositionResult(map, 1);
            result = JSONUtils.toJSON(map);
            return result;

        } catch (Exception e) {
            //清空map
            map.clear();
            map = OperateCode.CompositionResult(map, -1);
            result = JSONUtils.toJSON(map);
            return result;
        }
    }
    //endregion

    //region 删除&改变状态

    /**
     * 通过id删除 ajax异步
     *
     * @param id 记录id
     * @return json
     */
    @RequestMapping(value = "/deleteById", method = RequestMethod.POST)
    @ResponseBody
    public String deleteNotify(Integer id) {

        // 结果返回结果至少包含一个操作状态和一条状态信息
        String result = "";
        Map<String, String> map = new HashMap<String, String>();

        if (id == null || id <= 0) {
            map = OperateCode.CompositionResult(map, -10, "请选择要删除的记录！");
            result = JSONUtils.toJSON(map);
            return result;
        }

        try {
            Boolean isNext = lbsTerminalService.delete(id);
            map = OperateCode.CompositionResult(map, isNext ? 1 : 0);
            result = JSONUtils.toJSON(map);
            return result;

        } catch (Exception e) {
            //清空map
            map.clear();
            map = OperateCode.CompositionResult(map, -1);
            result = JSONUtils.toJSON(map);
            return result;
        }
    }

    /**
     * 状态改变 ajax异步
     *
     * @param id     记录id
     * @param status 状态
     * @return json
     */
    @RequestMapping(value = "/changeFlag", method = RequestMethod.POST)
    @ResponseBody
    public String openOrStopFlag(Integer id, Integer status) {

        // 结果返回 结果至少包含一个操作状态和一条状态信息
        String result = "";
        Map<String, String> map = new HashMap<String, String>();

        try {
            Boolean isNext = lbsTerminalService.changeState(id, status);
            map = OperateCode.CompositionResult(map, isNext ? 1 : 0);
            result = JSONUtils.toJSON(map);
            return result;

        } catch (Exception e) {
            //清空map
            map.clear();
            map = OperateCode.CompositionResult(map, -1);
            result = JSONUtils.toJSON(map);
            return result;
        }
    }
    //endregion

    //region 数据查看

    /**
     * 数据查看
     *
     * @param model     model模型
     * @param id        主键id
     * @param tableName 数据库英文表名
     * @return model
     */
    @RequestMapping(value = "/show", method = RequestMethod.POST)
    public String show(Model model, Integer id, String tableName) {
        id = (id == null ? 0 : id);

        LbsTerminalDTO obj = new LbsTerminalDTO();
        obj.setId(id);

        if (id > 0) {
            obj = lbsTerminalService.getById(id);
        }
        lbsTerminalService.assembleObjInfo(model, tableName, obj);

        return "show/show-template";
    }

    //endregion

    //region 查看终端位置
    @RequestMapping(value = "/viewPosition", method = RequestMethod.GET)
    public String viewPosition(Model model, Integer terminalId, String searchName, String myPosition, String myPositionName) {

        model.addAttribute("amapKey", amapKey);
        model.addAttribute("amapVersion", amapVersion);

        if (StringUtils.isBlank(myPosition)) {
            searchName = "";
        }
        model.addAttribute("searchName", searchName);
        model.addAttribute("myPosition", myPosition);
        model.addAttribute("myPositionName", myPositionName);

        String centerPosition = myPosition;
        List<Map<String, String>> pointList = new ArrayList<>();

        if (StringUtils.isNotBlank(myPosition)) {
            Map<String, String> map = new HashMap<>();
            map.put("name", myPositionName);
            map.put("x", myPosition.split(",")[0]);
            map.put("y", myPosition.split(",")[1]);
            map.put("time", "查询位置");
            pointList.add(map);
        }

        //取出所有的终端
        LbsTerminalDTOQuery terminalQuery = new LbsTerminalDTOQuery();
        if (terminalId != null && terminalId > 0) {
            terminalQuery.setId(terminalId);
        }
        terminalQuery.setStopFlag(0);
        Page<LbsTerminalDTO> terminalPage = lbsTerminalService.getForPage(terminalQuery);

        //取出最近的轨迹
        for (LbsTerminalDTO item : terminalPage.getItems()) {

            //取出新的坐标
            LbsTerminalStateDTO pointObj = lbsTerminalStateService.getByTerminalId(item.getId());

            if (pointObj != null) {
                Map<String, String> map = new HashMap<>();
                map.put("name", item.getTerminalName().split("的")[0]);
                map.put("x", pointObj.getLongitude());
                map.put("y", pointObj.getLatitude());
                map.put("time", pointObj.getLastUpdateTimeSr());

                pointList.add(map);

                if (StringUtils.isBlank(centerPosition)) {
                    centerPosition = pointObj.getLongitude() + "," + pointObj.getLatitude();
                }
            }
        }

        model.addAttribute("terminalId", terminalId);
        model.addAttribute("pointList", pointList);
        model.addAttribute("centerPosition", centerPosition);

        return "lbs/terminal/view-position";
    }
    //endregion

    //region 搜索
    @RequestMapping(value = "/poiSearch", method = RequestMethod.GET)
    public String poiSearch(Model model, String searchName, Integer terminalId) {

        model.addAttribute("amapKey", amapKey);
        model.addAttribute("amapVersion", amapVersion);

        model.addAttribute("searchName", searchName);
        model.addAttribute("terminalId", terminalId);

        return "lbs/terminal/poi-search";
    }
    //endregion

    //region 获取终端关联的用户和车辆
    @RequestMapping(value = "/getJoinInfo", method = RequestMethod.POST)
    @ResponseBody
    public Map<String, Object> getJoinInfo(HttpServletRequest request, Integer terminalId) {
        Map<String, Object> map = new HashMap<String, Object>();
        map.put("returnCode", 0);

        if (terminalId == null) {
            terminalId = 0;
        }

        if (terminalId > 0) {
            LbsTerminalDTO dto = lbsTerminalService.getById(terminalId);
            if (dto != null) {
                map.put("userId", dto.getUserId());
                map.put("userName", modelService.getUserTrueName(dto.getUserId()));
                map.put("carId", dto.getCarId());
            }

            //表示操作成功
            map.put("returnCode", 1);
        }

        return map;
    }
    //endregion

}